from PyQt5.QtWidgets import QGraphicsItem, QColorDialog, QFontDialog, QGraphicsTextItem
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QColor, QFont, QIcon, QPainter

from GUI import MainWindow
from GUI.Widget import ImageWindow
from GUI.Widget.ToolBar import ToolButton
from GUI.Widget.Editor.TextToolEditor import TextEditor


StartPos = None  # 文字开始点
OnNewText = False  # 正在新建文字
Window: MainWindow = None
Editor = None  # 编辑条
Tool = None  # 工具
TextLayerIcon = QIcon(':/tool/tool-text.png')   # 文本图层图标
GraphicsItemType = QGraphicsTextItem.UserType + 1



class GraphicsTextItem(QGraphicsTextItem):
    Type = GraphicsItemType
    imageLayer = None  # 所属图层
    compositionMode = QPainter.CompositionMode_SourceOver

    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        self.setAcceptDrops(False)
        # 可编辑
        self.setTextInteractionFlags(Qt.TextSelectableByMouse | Qt.TextSelectableByKeyboard | Qt.TextEditable)

    def paint(self, painter, style, widget=None):
        painter.setCompositionMode(self.compositionMode)
        QGraphicsTextItem.paint(self, painter, style, widget)


class TextToolEditor(TextEditor):
    info = {}

    def __init__(self, window, parent, tool):
        super().__init__(window, parent, tool)
        self.initUI(parent)

    def initUI(self, panel):
        # 部件
        self.info['text'] = 'Photo Sprite Little'
        self.initFontLabel()
        self.initColorLabel()

    def initFontLabel(self):
        # 字体
        fontButton = self.fontButton
        font = QFont('Microsoft YaHei UI', 10)
        fontButton.setFont(font)
        fontButton.setText(font.family())
        fontButton.mousePressEvent = self.pressFontButton  # register clickEvent
        fontSizeLabel = self.fontSizeLabel
        fontSizeLabel.setText(str(font.pointSize()))
        self.info['font'] = font

    def initColorLabel(self):
        colorLabel = self.colorLabel
        color = QColor(255, 255, 255)
        styleSheet = 'background-color:{0}'.format(color.name())
        colorLabel.setStyleSheet(styleSheet)
        colorLabel.setText('')
        self.info['color'] = color
        colorLabel.mousePressEvent = self.pressColorLabel  # register clickEvent

    def pressColorLabel(self, event):
        # 检查是否正在编辑当前图层的文本项目
        flag = False
        win: MainWindow = self.window
        layer = win.currentLayer
        if layer and layer.layerType == 'text':
            graphicsItem = getattr(layer, 'graphicsItem', None)
            if graphicsItem and graphicsItem.hasFocus():
                flag = True

        label = self.colorLabel
        colorWindow = QColorDialog(QColor(255, 255, 255))
        color = colorWindow.getColor()
        if color.isValid():
            label.color = color.name()
            styleSheet = 'background-color:{0}'.format(color.name())
            label.setStyleSheet(styleSheet)
            self.info['color'] = color
            # 更新当前 图层的文本
            if flag:
                graphicsItem.setDefaultTextColor(color)

    def pressFontButton(self, event):
        # 检查是否正在编辑当前图层的文本项目
        flag = False
        win = self.window
        layer = win.currentLayer
        if layer and layer.layerType == 'text':
            graphicsItem = getattr(layer, 'graphicsItem', None)
            if graphicsItem and graphicsItem.hasFocus():
                flag = True

        button = self.fontButton
        font, ok = QFontDialog.getFont(self.info['font'])
        if ok:
            button.setText(font.family())
            displayFont = QFont(font)
            displayFont.setPointSize(10)
            button.setFont(displayFont)
            fontSizeLabel = self.fontSizeLabel
            fontSizeLabel.setText(str(font.pointSize()))
            self.info['font'] = font
            # 更新当前 图层的文本
            if flag:
                graphicsItem.setFont(font)
                graphicsItem.adjustSize()


def init(window, tool: ToolButton):
    global App
    global Window
    global Editor
    global Tool
    Window = window
    Tool = tool
    editorPanel = window.editorPanel
    Editor = TextToolEditor(window, editorPanel, tool)
    Editor.window = window
    tool.editor = Editor
    # 工具在视图中的事件
    tool.mousePressGraphicsViewEventCallBack = startText  # 开始绘制
    tool.mouseMoveGraphicsViewEventCallBack = move  # 鼠标移动绘制
    tool.mouseReleaseGraphicsViewEventCallBack = endText  # 结束绘制
    # 工具焦点事件
    tool.toolFocusOffLayerEvent = toolFocusOffLayerEvent
    tool.toolFocusOnLayerEvent = toolFocusOnLayerEvent
    # 工具开关事件
    tool.deselectToolEvent = deselectToolEvent


def toolFocusOffLayerEvent(tool, layer):
    """
    逝去工具焦点
    :param tool:
    :param layer:
    :return:
    """
    graphicsItem = layer.graphicsItem
    if not graphicsItem.type() == GraphicsItemType:
        return
    # 不可移动
    graphicsItem.setFlag(QGraphicsItem.ItemIsMovable, False)
    # 不可编辑
    graphicsItem.setTextInteractionFlags(Qt.NoTextInteraction)


def toolFocusOnLayerEvent(tool, layer):
    """
    获得工具焦点
    :param tool:
    :param layer:
    :return:

    """
    graphicsItem = layer.graphicsItem
    if not graphicsItem.Type == GraphicsItemType:
        return
    # 可移动
    graphicsItem.setFlag(QGraphicsItem.ItemIsMovable, True)
    # 可编辑
    graphicsItem.setTextInteractionFlags(Qt.TextSelectableByMouse | Qt.TextSelectableByKeyboard | Qt.TextEditable)
    # graphicsItem.setTextInteractionFlags(Qt.TextEditable)


def deselectToolEvent(tool):
    """
    取消选择工具事件
    :param tool:
    :return:
    """
    win = Window
    imageWindow: ImageWindow = win.currentImageWindow
    textItems = imageWindow.forItemsInScene(_forItemInSceneFilter)
    for each in textItems:
        each.setTextInteractionFlags(Qt.NoTextInteraction)  # 不可编辑
    imageWindow.view.trackMouseMove = False  # 不允许跟踪鼠标移动


def _forItemInSceneFilter(item):
    # print('item type:', item.Type, '模板', GraphicsItemType)
    if item.Type == GraphicsItemType:
        return True
    else:
        return False


def _checkTextItemFilter(item):
    """
    检查当前鼠标下是否存在 GraphicsTextItem
    :param item: GraphicsTextItem
    :return:
    """
    if item.Type == GraphicsItemType and item.isEnabled():
        return True
    else:
        return False


def startText(tool, event):
    global StartPos
    global OnNewText
    OnNewText = False

    pos = event.pos()
    win = Window
    imageWindow: ImageWindow = win.currentImageWindow
    view = imageWindow.view
    items = imageWindow.forItemAtPoint(view.mapToScene(pos), _forItemInSceneFilter)
    if len(items) > 0:
        return
    # scene = win.scene
    view.trackMouseMove = True   # 允许跟踪鼠标移动
    StartPos = pos
    # print('开始写字')


def move(tool ,event):
    global OnNewText
    if not OnNewText:
        OnNewText = True
        print('正在写字')


def endText(tool, event):
    """
    :param tool: 当前工具
    :param event:
    :return:
    """
    global StartPos
    global OnNewText
    win = Window
    imageWindow: ImageWindow = win.currentImageWindow
    view = imageWindow.view
    view.trackMouseMove = False  # 不允许跟踪鼠标移动
    if not OnNewText:   # 未移动鼠标，不创建文本
        return
    view = imageWindow.view
    if StartPos:
        pos = view.mapToScene(StartPos)
        StartPos = None
    else:
        pos = view.mapToScene(event.pos())
    newTextLayer(None, pos)
    OnNewText = False
    StartPos = None
    # print('结束写字')


def newTextLayer(info, pos):
    win = Window
    imageWindow: ImageWindow = win.currentImageWindow
    defaultInfo = Editor.info
    if info is dict:
        text = info.get('text')
        if text is None:
            text = defaultInfo['text']
        name = info.get('name')
        if name is None:
            name = text
        font = info.get('font')
        if font is None:
            font = defaultInfo['font']
        color = info.get('color')
        if color is None:
            color = defaultInfo['color']
    else:
        text = defaultInfo['text']
        name = text
        font = defaultInfo['font']
        color = defaultInfo['color']

    scene = imageWindow.scene
    textItem = GraphicsTextItem()
    textItem.setPlainText(text)
    textItem.setFont(font)
    textItem.setDefaultTextColor(color)
    textItem.adjustSize()
    scene.addItem(textItem)
    textItem.setPos(pos)
    textItem.setFocus(Qt.MouseFocusReason)  # 设置焦点
    # textItem.setSelected(True)
    # 图层
    layer = imageWindow.imageLayer
    newLayer = layer.newLayer({
        'name': name,
        'graphicsItem': textItem,
        'layerType': 'text',
        'icon': TextLayerIcon,
    })
    textItem.imageLayer = newLayer
    # layer.setSelectedWindow(newLayer)


